package com.san.oms.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.san.base.controller.BaseController;
import com.san.base.domain.Tree;
import com.san.common.utils.R;
import com.san.oms.domain.ModelScDTO;
import com.san.oms.domain.QuotaDO;
import com.san.oms.domain.QuotaRuleDTO;
import com.san.oms.domain.ScoreLevelDO;
import com.san.oms.service.ModelService;
import com.san.oms.service.QuotaService;
import com.san.oms.service.ScoreLevelService;
import com.san.oms.vo.QuotaVO;

/**
 * 监测模型业务控制器
 * 
 * @author Administrator
 *
 */
@RequestMapping("/ce/quota")
@Controller
public class QuotaController extends BaseController {
	
	private static final Logger logger = LoggerFactory.getLogger(QuotaController.class);

	/**
	 * 本功能地址前缀
	 */
	private static final String PREFIX = "ce/quota";

	@Autowired
	QuotaService service;
	
	@Autowired
	ModelService modelService;
	
	@Autowired
	ScoreLevelService scoreLevelService;

	/**
	 * 模型指标列表页
	 * 
	 * @param model
	 * @return
	 */
	@GetMapping("view/{modelId}/{modelType}")
	@RequiresPermissions("ce:quota:view")
	String view(Model model, @PathVariable("modelId") Long modelId,@PathVariable("modelType") String modelType) {
		model.addAttribute("modelId", modelId);
		model.addAttribute("modelType",modelType);
		return PREFIX + "/view";
	}

	/**
	 * 获取指标模型数据
	 * 
	 * @return
	 */
	@GetMapping("quotaList")
	@RequiresPermissions("ce:quota:view")
	@ResponseBody
	List<QuotaDO> quotaList(@RequestParam Map<String, Object> params) {
		List<QuotaDO> list = null;
		try {
			String modelId = (String)params.get("modelId");
			if (null == modelId || "".equals(modelId)) {
				return new ArrayList<QuotaDO>();
			}
			
			Long mid = Long.parseLong(modelId);
			
			list = service.getQuotaList(mid);
		} catch (Exception e) {
			list = new ArrayList<QuotaDO>();
			logger.error("获取指标列表出错",e);
		}

		return list;
	}

	/**
	 * 模型指标新增页面
	 * 
	 * @param model
	 * @param pId
	 * @return
	 */
	@GetMapping("/add/{pId}/{modelId}/{modelType}")
	@RequiresPermissions("ce:quota:add")
	String add(Model model, @PathVariable("pId") Long pId, @PathVariable("modelId") Long modelId, @PathVariable("modelType") String modelType) {
		model.addAttribute("pId", pId);
		model.addAttribute("modelId", modelId);
		model.addAttribute("modelType", modelType);
		try {
			if (null != pId && pId.longValue() != 0) {
				QuotaDO quotaDO = (QuotaDO) service.getById(pId);
				model.addAttribute("pName", quotaDO.getQuotaName());
			} else {
				ModelScDTO modelDO = (ModelScDTO) modelService.getById(modelId);
				model.addAttribute("pName", modelDO.getModelName());
			}
			
		} catch (Exception e) {
			logger.error("获取父级指标出错",e);
		}
		return PREFIX + "/add";
	}

	/**
	 * 保存模型指标项
	 * 
	 * @param vo
	 * @return
	 */
	@PostMapping("/save")
	@RequiresPermissions("ce:quota:add")
	@ResponseBody
	R save(QuotaVO vo) {
		R r = validate(vo);
		if (!"0".equals(r.get("code").toString())) {
			return r;
		}

		int result = 0;
		try {
			result = service.save(vo);
		} catch (Exception e) {
			logger.error("指标保存出错",e);
		}

		if (result > 0) {
			return R.ok();
		} else {
			return R.error(1, "保存失败");
		}
	}

	/**
	 * 模型指标修改页面
	 * 
	 * @param model
	 * @param id
	 * @return
	 */
	@GetMapping("/edit/{id}/{modelType}")
	@RequiresPermissions("ce:quota:edit")
	String edit(Model model, @PathVariable("id") Long id, @PathVariable("modelType") String modelType) {
		try {
			QuotaDO quotaDO = (QuotaDO) service.getById(id);
			long pId = quotaDO.getParentId();
			model.addAttribute("pId", pId);
			model.addAttribute("modelType",modelType);
			QuotaDO parentQuotaDO = (QuotaDO) service.getById(pId);
			model.addAttribute("pName", null == parentQuotaDO ? "根节点" : parentQuotaDO.getQuotaName());

			model.addAttribute("quotaDO", quotaDO);
		} catch (Exception e) {
			logger.error("获取指标数据出错",e);
		}
		return PREFIX + "/edit";
	}

	/**
	 * 保存模型指标项
	 * 
	 * @param vo
	 * @return
	 */
	@PostMapping("/doEdit")
	@RequiresPermissions("ce:quota:edit")
	@ResponseBody
	R doEdit(QuotaVO vo) {
		R r = validate(vo);
		if (!"0".equals(r.get("code").toString())) {
			return r;
		}

		int result = 0;
		try {
			result = service.doEdit(vo);
		} catch (Exception e) {
			logger.error("更新指标出错",e);
		}

		if (result > 0) {
			return R.ok();
		} else {
			return R.error(1, "保存失败");
		}
	}

	/**
	 * 删除指标
	 * 
	 * @param id
	 * @return
	 */
	@PostMapping("/remove")
	@RequiresPermissions("ce:quota:remove")
	@ResponseBody
	R remove(Long id) {
		try {
			if (service.remove(id) > 0) {
				return R.ok();
			}
		} catch (Exception e) {
			logger.error("删除指标列表出错",e);
		}
		return R.error();
	}

	/**
	 * 指标内容校验
	 * 
	 * @param vo
	 * @return
	 */
	public R validate(QuotaVO vo) {
		if (null == vo.getQuotaName() || "".equals(vo.getQuotaName())) {
			return R.error("指标名称为空");
		}

		if (!checkQuotaName(vo)) {
			return R.error("指标名称已存在");
		}

		if (!checkScore(vo)) {
			return R.error("指标总分数超出父级分数");
		}
		
		return checkRule(vo);
	}

	/**
	 * 校验模型指标名称
	 * 
	 * @param vo
	 * @return
	 */
	public boolean checkQuotaName(QuotaVO vo) {
		boolean result = true;
		try {
			Map<String, Object> condition = new HashMap<String, Object>();
			condition.put("quotaName", vo.getQuotaName());
			condition.put("modelId", vo.getModelId());
			List<QuotaDO> quotaList = service.findQuotaList(condition);
			for (QuotaDO quotaDO : quotaList) {
				if (null == vo.getQuotaId() || vo.getQuotaId() == 0) {
					// 新增时，只需要判断名称在数据库中是否存在
					if (vo.getQuotaName().equals(quotaDO.getQuotaName())) {
						result = false;
						break;
					}
				} else {
					// 修改时，需要排除自身数据
					if (vo.getQuotaName().equals(quotaDO.getQuotaName())
							&& vo.getQuotaId().longValue() != quotaDO.getQuotaId().longValue()) {
						result = false;
						break;
					}
				}
			}
		} catch (Exception e) {
			result = false;
			logger.error("校验指标名称出错",e);
		}

		return result;
	}

	/**
	 * 校验指标得分
	 * 
	 * @param vo
	 * @return
	 */
	public boolean checkScore(QuotaVO vo) {
		if (0 == vo.getQuotaScore()) {
			return true;
		}
		boolean result = true;
		try {
			int parentScore = 0;
			if(vo.getParentId().longValue() == 0) {
				ModelScDTO modelScDO = (ModelScDTO)modelService.getById(vo.getModelId());
				ScoreLevelDO scoreLevelDO = scoreLevelService.getById(modelScDO.getScoreId());
				//parentScore = modelDO.getModelScore();
				parentScore = scoreLevelDO.getScoreTotal();
			} else {
				QuotaDO parentQuotaDO = (QuotaDO) service.getById(vo.getParentId());
				parentScore = parentQuotaDO.getQuotaScore();
			}
			

			List<QuotaDO> list = service.findSubset(vo.getModelId(),vo.getParentId());

			double subsetScore = vo.getQuotaScore();
			for (QuotaDO quotaDO : list) {
				if (0 != quotaDO.getQuotaScore()) {
					if (null != vo.getQuotaId() && vo.getQuotaId().longValue() == quotaDO.getQuotaId().longValue()) {
						// 修改时不再累加自身以前的权重
						continue;
					}
					subsetScore += quotaDO.getQuotaScore();
					
				}
			}
			
			if (parentScore > 0) {
				if (subsetScore > parentScore) {
					result = false;
				}
			} else {
				if (subsetScore < parentScore) {
					result = false;
				}
			}

		} catch (Exception e) {
			result = false;
			logger.error("校验指标总分出错",e);
		}

		return result;
	}
	
	/**
	 * 校验指标规则
	 * 
	 * @param vo
	 * @return
	 */
	public R checkRule(QuotaVO vo) {
		String quotaRule = vo.getQuotaRule();
		
		if (null != quotaRule && !"".equals(quotaRule)) {
			if (vo.getQuotaType() == 1) {
				//加权，系数必须为整数
				try {
					Integer.parseInt(vo.getQuotaRule());
				} catch(Exception e) {
					return R.error("加权算法，规则请输入正整数");
				}
			} else if (vo.getQuotaType() == 2) {
				//区间
				try {
					String[] rules = quotaRule.split("\\|");
					List<QuotaRuleDTO> list = new ArrayList<QuotaRuleDTO>();
					
					QuotaRuleDTO dto = null;
					for (String rule : rules) {
						String[] section = rule.split(",");
						dto = new QuotaRuleDTO();
						
						dto.setNum(section[0].equals("~") ? 999999999 : Integer.parseInt(section[0]));
						dto.setScore(Integer.parseInt(section[1]));
						list.add(dto);
					}
				} catch(Exception e) {
					return R.error("区间算法，规则请输入正确格式");
				}
			}
		}
		
		return R.ok();
	}
	
//	@PostMapping("/checkChild")
//	@ResponseBody
//	public R checkChild(Long id) {
//		if (null == id || id == 0) {
//			return R.error("请选择子指标");
//		}
//
//		List<QuotaDO> list;
//		try {
//			list = service.findSubset(id);
//			if (null != list && list.size() > 0) {
//				return R.error("请选择子指标");
//			} else {
//				return R.ok();
//			}
//		} catch (Exception e) {
//			logger.error("校验子指标出错",e);
//		}
//
//		return R.ok();
//	}

	@GetMapping("/quotaTree")
	@ResponseBody
	public Tree<QuotaDO> quotaTree() {
		Tree<QuotaDO> tree = new Tree<QuotaDO>();
		try {
			tree = service.getQuotaTree();
		} catch (Exception e) {
			logger.error("获取指标树出错",e);
		}
		return tree;
	}

}
